package dohmh.yelp.classifiers;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

import weka.classifiers.Classifier;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import dohmh.yelp.dataobjects.Classification;
import dohmh.yelp.dataobjects.Review;
import dohmh.yelp.exceptions.DOHMHException;

public class WekaClassifier extends AbstractClassifier {
	private String _path;
	private Classifier _cls;
	private String [] _classValues;
	private Instances _data;
	public WekaClassifier(String path, String [] classValues) throws FileNotFoundException, IOException{
		_path = path;
		_classValues = classValues;
		
		// Create vector of attributes.
	    FastVector attributes = new FastVector(2);

	    // Add attribute for holding review.
	    attributes.addElement(new Attribute("Review", (FastVector)null));
	    
	    // Add class attribute.
	    FastVector cValues = new FastVector(_classValues.length);
	    for (int i = 0; i < _classValues.length; i++){
	    	cValues.addElement(_classValues[i]);
	    }
	    attributes.addElement(new Attribute("Class", cValues));

		_data = new Instances("", attributes, 1);
		_data.setClassIndex(_data.numAttributes() - 1);
	    
		ObjectInputStream ois = null;
		ois = new ObjectInputStream(new FileInputStream(_path));
		try {
			_cls = (Classifier) ois.readObject();
		} catch (ClassNotFoundException e) {
			System.out.println("Class not found: " + e.getClass().toString());
			e.printStackTrace();
		} finally {
			ois.close();	
		}
	}

	public Classification classify(Review r) throws DOHMHException {
		// Make review into test instance.
	    Instance instance = makeInstance(r.getText());
	    Classification retVal = new Classification();
	    try {
	    	retVal.setClasses(_classValues);
			retVal.setConfidenceScores(_cls.distributionForInstance(instance));
		} catch (Exception e) {
			throw new DOHMHException(e);
		}
		return retVal;
	}
	
	private Instance makeInstance(String text) {
	    // Create instance of length two.
	    Instance instance = new Instance(2);

	    Instances testSet = _data.stringFreeStructure();
	    
	    // Set value for review attribute
	    Attribute reviewAtt = testSet.attribute("Review");
	    instance.setValue(reviewAtt, reviewAtt.addStringValue(text));

	    // Give instance access to attribute information from the dataset.
	    instance.setDataset(testSet);
	    return instance;
	  }
}
